namespace SimpleWebServices.Data
{
    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Data.SqlTypes;
    using System.Globalization;
    using System.IO;
    using System.Xml;
    using System.Xml.XPath;

    public static class SqlParameterCollectionExtensionMethods
    {
        public static void AddChar(this SqlParameterCollection collection, string parameterName, string value, int size)
        {
            if (null == parameterName)
            {
                throw new ArgumentNullException("parameterName");
            }
            else if (0 == parameterName.Length)
            {
                throw new ArgumentOutOfRangeException("parameterName");
            }
            else if (null == value)
            {
                throw new ArgumentNullException("value");
            }

            SqlParameter parameter = new SqlParameter(parameterName, SqlDbType.Char, size);
            parameter.Value = value;

            collection.Add(parameter);
        }

        public static void AddDateTime(this SqlParameterCollection collection, string parameterName, DateTime value)
        {
            if (null == parameterName)
            {
                throw new ArgumentNullException("parameterName");
            }
            else if (0 == parameterName.Length)
            {
                throw new ArgumentOutOfRangeException("parameterName");
            }

            SqlParameter parameter = new SqlParameter(parameterName, SqlDbType.DateTime);
            parameter.Value = value;

            collection.Add(parameter);
        }

        public static void AddInt32(this SqlParameterCollection collection, string parameterName, int value)
        {
            if (null == parameterName)
            {
                throw new ArgumentNullException("parameterName");
            }
            else if (0 == parameterName.Length)
            {
                throw new ArgumentOutOfRangeException("parameterName");
            }

            SqlParameter parameter = new SqlParameter(parameterName, SqlDbType.Int);
            parameter.Value = value;

            collection.Add(parameter);
        }

        public static void AddNVarChar(this SqlParameterCollection collection, string parameterName, string value, int size)
        {
            if (null == parameterName)
            {
                throw new ArgumentNullException("parameterName");
            }
            else if (0 == parameterName.Length)
            {
                throw new ArgumentOutOfRangeException("parameterName");
            }
            else if (null == value)
            {
                throw new ArgumentNullException("value");
            }

            SqlParameter parameter = new SqlParameter(parameterName, SqlDbType.NVarChar, size);
            parameter.Value = value;

            collection.Add(parameter);
        }

        public static void AddToken(this SqlParameterCollection collection, string parameterName, Guid value)
        {
            if (null == parameterName)
            {
                throw new ArgumentNullException("parameterName");
            }
            else if (0 == parameterName.Length)
            {
                throw new ArgumentOutOfRangeException("parameterName");
            }

            SqlParameter parameter = new SqlParameter(parameterName, SqlDbType.UniqueIdentifier);
            parameter.Value = value;

            collection.Add(parameter);
        }

        public static void AddVarChar(this SqlParameterCollection collection, string parameterName, string value, int size)
        {
            if (null == parameterName)
            {
                throw new ArgumentNullException("parameterName");
            }
            else if (0 == parameterName.Length)
            {
                throw new ArgumentOutOfRangeException("parameterName");
            }
            else if (null == value)
            {
                throw new ArgumentNullException("value");
            }

            SqlParameter parameter = new SqlParameter(parameterName, SqlDbType.VarChar, size);
            parameter.Value = value;

            collection.Add(parameter);
        }

        public static void AddXml(this SqlParameterCollection collection, string parameterName, IXPathNavigable xml)
        {
            if (null == xml)
            {
                throw new ArgumentNullException("xml");
            }

            using (MemoryStream stream = new MemoryStream())
            {
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.Write(xml.CreateNavigator().OuterXml);
                    writer.Flush();

                    stream.Position = 0;

                    using (XmlReader reader = new XmlTextReader(stream))
                    {
                        collection.AddXml(parameterName, reader);
                    }
                }
            }
        }

        public static void AddXml(this SqlParameterCollection collection, string parameterName, XmlReader reader)
        {
            if (null == reader)
            {
                throw new ArgumentNullException("reader");
            }

            collection.AddXml(parameterName, new SqlXml(reader));
        }

        public static void AddXml(this SqlParameterCollection collection, string parameterName, SqlXml value)
        {
            if (null == parameterName)
            {
                throw new ArgumentNullException("parameterName");
            }
            else if (0 == parameterName.Length)
            {
                throw new ArgumentOutOfRangeException("parameterName");
            }
            else if (null == value)
            {
                throw new ArgumentNullException("value");
            }

            SqlParameter parameter = new SqlParameter(parameterName, SqlDbType.Xml);
            parameter.Value = value;

            collection.Add(parameter);
        }
    }
}